package com.example.controller;

import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.common.Result;
import com.example.enums.UploadEnum;
import com.example.pojo.User;
import com.example.service.UserService;
import io.minio.MinioClient;
import io.minio.errors.*;
import io.minio.policy.PolicyType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.lang.reflect.Method;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Api(tags = "MinioController", description = "MinIO对象存储管理")
@RestController
@RequestMapping("/minio")
@Slf4j
public class MinioController {
    @Autowired
    UserService userService;
    @Value("${minio.endpoint}")
    private String ENDPOINT;
    @Value("${minio.bucketName}")
    private String BUCKET_NAME;
    @Value("${minio.accessKey}")
    private String ACCESS_KEY;
    @Value("${minio.secretKey}")
    private String SECRET_KEY;
    @Value("${minio.nginxPath}")
    private String NGINX_PATH;

    public String upload(MultipartFile file) throws Exception {
        MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
        boolean isExist = minioClient.bucketExists(BUCKET_NAME);
        if (isExist) {
            log.info("桶已存在");
        } else {
            minioClient.makeBucket(BUCKET_NAME);
            minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
        }
        String filename = file.getOriginalFilename();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String objectName = sdf.format(new Date()) + filename;
        minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());
        log.info("文件上传成功");
        String url = "/img" + "/" + BUCKET_NAME + "/" + objectName;
        return url;
    }

    @ApiOperation("图片上传")
    @PostMapping("/upload")
    public Result uploadImg(@RequestParam("file") MultipartFile file) {
        return getResult(file, UploadEnum.UPLOAD_IMG);
    }

    @ApiOperation("背景上传")
    @PostMapping("/uploadBackground")
    public Result uploadBackground(@RequestParam("file") MultipartFile file) {
        return getResult(file, UploadEnum.UPLOAD_BACKGROUND);
    }

    private Result getResult(MultipartFile file, UploadEnum uploadEnum) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        try {

            String url = upload(file);
            ReflectUtil.invoke(user, uploadEnum.getSetPropertyMethod(), url);
            ReflectUtil.invoke(userService, uploadEnum.getUploadMethod(), user);
            JSONObject result = new JSONObject();
            result.put(uploadEnum.getResultKey(), url);
            return Result.SUCCESS(result);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.FAIL("上传失败");
        }
    }
}
